home *** CD-ROM | disk | FTP | other *** search
/ Aminet 3 / Aminet 3 - July 1994.iso / Aminet / misc / unix / tracker_4_3.lzh / tracker / automaton.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-13  |  5.7 KB  |  239 lines

  1. /* automaton.c 
  2.     vi:se ts=3 sw=3:
  3.  */
  4.  
  5. /* $Id: automaton.c,v 4.0 1994/01/11 17:42:13 espie Exp espie $
  6.  * $Log: automaton.c,v $
  7.  * Revision 4.0  1994/01/11  17:42:13  espie
  8.  * Abstracted IO calls.
  9.  *
  10.  * Revision 1.5  1994/01/09  23:24:37  Espie
  11.  * Last bug fix.
  12.  *
  13.  * Revision 1.4  1994/01/09  17:36:22  Espie
  14.  * Generalized open.c.
  15.  *
  16.  * Revision 1.3  1994/01/05  14:54:09  Espie
  17.  * *** empty log message ***
  18.  *
  19.  * Revision 1.2  1993/12/28  13:54:44  Espie
  20.  * Use display_pattern.
  21.  *
  22.  * Revision 1.1  1993/12/26  00:55:53  Espie
  23.  * Initial revision
  24.  *
  25.  * Revision 3.16  1993/12/04  16:12:50  espie
  26.  * *** empty log message ***
  27.  *
  28.  * Revision 3.15  1993/11/17  15:31:16  espie
  29.  * *** empty log message ***
  30.  *
  31.  * Revision 3.13  1993/07/18  10:39:44  espie
  32.  * Fixed up repeat code, should work better now.
  33.  *
  34.  * Revision 3.12  1993/07/17  22:23:41  espie
  35.  * Fixed bug with bad loops.
  36.  *
  37.  * Revision 3.9  1993/05/09  14:06:03  espie
  38.  * Modified the way set_speed works.
  39.  *
  40.  * Revision 3.8  1993/01/16  17:00:27  espie
  41.  * Corrected stupid bug (run_in_fg)
  42.  *
  43.  * Revision 3.7  1993/01/15  14:00:28  espie
  44.  * Added bg/fg test.
  45.  *
  46.  * Revision 3.6  1992/11/27  10:29:00  espie
  47.  * General cleanup
  48.  *
  49.  * Revision 3.5  1992/11/24  10:51:19  espie
  50.  * un#ifdef'ed showseq code.
  51.  *
  52.  * Revision 3.3  1992/11/22  17:20:01  espie
  53.  * Simplified delay_pattern.
  54.  *
  55.  * Revision 3.2  1992/11/20  14:53:32  espie
  56.  * Added finetune.
  57.  *
  58.  * Revision 3.1  1992/11/19  20:44:47  espie
  59.  * Protracker commands.
  60.  *
  61.  * Revision 3.0  1992/11/18  16:08:05  espie
  62.  * New release.
  63.  *
  64.  * Revision 2.16  1992/11/17  17:15:37  espie
  65.  * New output for new interface
  66.  * Modified repeat logic: now works irregardless of repeat points.
  67.  * start
  68.  *
  69.  * Revision 2.8  1992/07/14  14:23:41  espie
  70.  * Changed fine speed command and comments.
  71.  * Added two level of fault tolerancy.
  72.  */
  73.      
  74.  
  75. #include <stdio.h>
  76. #include <stdlib.h>
  77. #include <string.h>
  78.      
  79. #include "defs.h"
  80. #include "song.h"
  81. #include "channel.h"
  82. #include "extern.h"
  83.      
  84. ID("$Id: automaton.c,v 4.0 1994/01/11 17:42:13 espie Exp espie $")
  85.      
  86.  
  87. LOCAL void clear_repeats(a, from, upto)
  88. struct automaton *a;
  89. int from, upto;
  90.    {
  91.    int i;
  92.  
  93.    for (i = from; i <= upto; i++)
  94.       a->gonethrough[i] = FALSE;
  95.    }
  96.  
  97. LOCAL void reset_repeats(a)
  98. struct automaton *a;
  99.    {
  100.    clear_repeats(a, 0, a->info->length);
  101.    a->gonethrough[a->info->length] = TRUE;
  102.    }
  103.  
  104. /* updates the pattern to play in the automaton.
  105.  * Checks that the pattern actually exists.
  106.  * Checks for repetitions as well.
  107.  */
  108. LOCAL void set_pattern(a)
  109. struct automaton *a;
  110.    {
  111.    int p;
  112.  
  113.  
  114.    if (a->pattern_num >= a->info->length)
  115.       {
  116.       error = UNRECOVERABLE;
  117.       return;
  118.       }
  119.  
  120.    if (a->gonethrough[a->pattern_num])
  121.       {
  122.       error = ENDED;
  123.       reset_repeats(a);
  124.       }
  125.    else
  126.       a->gonethrough[a->pattern_num] = TRUE;
  127.  
  128.    display_pattern(a->pattern_num, a->info->length);
  129.  
  130.       /* there is a level of indirection in the format,
  131.        * i.e., patterns can be repeated.
  132.        */
  133.    p = a->info->patnumber[a->pattern_num];
  134.    if (p >= a->info->maxpat)
  135.       {
  136.       error = UNRECOVERABLE;
  137.       return;
  138.       }
  139.    a->pattern = a->info->pblocks + p;
  140.    }
  141.  
  142. /* initialize all the fields of the automaton necessary
  143.  * to play a given song.
  144.  */
  145. void init_automaton(a, song, start)
  146. struct automaton *a;
  147. struct song *song;
  148. int start;
  149.    {
  150.    a->info = &song->info;
  151.    a->pattern_num = start;    /* first pattern */
  152.  
  153.    a->loop_note_num = 0;
  154.    a->loop_counter = 0;
  155.  
  156.    reset_repeats(a);
  157.  
  158.    a->note_num = 0;           /* first note in pattern */
  159.    a->counter = 0;            /* counter for the effect tempo */
  160.    a->speed = NORMAL_SPEED;   /* this is the default effect tempo */
  161.    a->finespeed = NORMAL_FINESPEED;    
  162.                               /* this is the fine speed (100%=NORMAL_FINESPEED) */
  163.    a->do_stuff = DO_NOTHING;   
  164.                               /* some effects affect the automaton,
  165.                                * we keep them here.
  166.                                */
  167.  
  168.    error = NONE;              /* Maybe we should not reset errors at
  169.                                * this point.
  170.                                */
  171.    set_pattern(a);
  172.    }
  173.  
  174. /* Gets to the next pattern, and displays stuff */
  175. LOCAL void advance_pattern(a)
  176. struct automaton *a;
  177.    {
  178.    if (++a->pattern_num >= a->info->length)
  179.       a->pattern_num = 0;
  180.    set_pattern(a);
  181.    a->note_num = 0;
  182.    }
  183.  
  184.         
  185.  
  186. /* process all the stuff which we need to advance in the song,
  187.  * including set_speed, set_skip, set_fastskip, and set_loop.
  188.  */
  189. void next_tick(a)
  190. struct automaton *a;
  191.    {
  192.       /* there are three classes of speed changes:
  193.        * 0 does nothing. (should stop)
  194.        * <32 is the effect speed (resets the fine speed).
  195.        * >=32 changes the finespeed, default 125
  196.        */
  197.    if ((a->do_stuff & SET_SPEED) && (a->do_stuff & SET_FINESPEED))
  198.       {
  199.       a->speed = a->new_speed;
  200.       a->finespeed = a->new_finespeed;
  201.       }
  202.    else if (a->do_stuff & SET_FINESPEED)
  203.       {
  204.       a->finespeed = a->new_finespeed;
  205.       }
  206.    else if (a->do_stuff & SET_SPEED)
  207.       {
  208.       a->speed = a->new_speed;
  209.       a->finespeed = NORMAL_FINESPEED;
  210.       }
  211.  
  212.    if (++a->counter >= a->speed)
  213.       {
  214.       a->counter = 0;
  215.          /* loop: may change note in pattern right away */
  216.       if ((a->do_stuff & JUMP_PATTERN) && --a->loop_counter > 0)
  217.          a->note_num = a->loop_note_num;
  218.       else if (a->do_stuff & SET_FASTSKIP)
  219.          {
  220.          a->pattern_num = a->new_pattern;
  221.          set_pattern(a);
  222.          a->note_num = 0;
  223.          }
  224.       else if (a->do_stuff & SET_SKIP)
  225.          {
  226.          advance_pattern(a);
  227.          a->note_num = a->new_note;
  228.          }
  229.       else
  230.          {
  231.          if (++a->note_num >= BLOCK_LENGTH)
  232.             advance_pattern(a);
  233.          }
  234.       a->do_stuff = DO_NOTHING;
  235.       }
  236.    }
  237.  
  238.  
  239.